package com.hxzy.springbootrocketproducer.service;

import com.hxzy.springbootrocketproducer.dto.UserChargeDTO;
import com.hxzy.springbootrocketproducer.entity.MqTransactionLog;
import com.hxzy.springbootrocketproducer.mapper.MqTransactionLogMpper;
import lombok.extern.log4j.Log4j2;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;

/**
 * RocketMQ本地事务
 */
@Log4j2
@RocketMQTransactionListener
public class MQTXLocalService implements RocketMQLocalTransactionListener {

    @Autowired
    private UserService userService;

    @Autowired
    private MqTransactionLogMpper  mqTransactionLogMpper;

    /**
     * 1、本地事务执行操作
     * @param message
     * @param o
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        //1、接收消息 ( 用户冲值对象UserChargeDTO , TRANSACTION_ID 事务UUID标识)
        // 获取消息体里参数
        MessageHeaders messageHeaders = message.getHeaders();
        String transactionId = (String) messageHeaders.get(RocketMQHeaders.TRANSACTION_ID);
        log.info("【第一次执行本地事务】消息体参数：transactionId={}", transactionId);

        //2、取得消息内容
        UserChargeDTO  userChargeDTO= (UserChargeDTO) o;

        //3、尝试调用 冲值方法
        try{
            this.userService.addBalance(userChargeDTO, transactionId);
            //回调给RocketMQ通知 本地事务成功 正常：向RocketMQ Server发送commit消息
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
           log.error("【执行本地事务】发生异常，消息将被回滚", e);
            // 异常：向MQ Server发送rollback消息
           return RocketMQLocalTransactionState.ROLLBACK;
         }

    }

    /**
     * 2、RocketMq事务自动回查状态 (二次确认)
     * @param message
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        // 获取消息体里参数
        MessageHeaders messageHeaders = message.getHeaders();
        String transactionId = (String) messageHeaders.get(RocketMQHeaders.TRANSACTION_ID);
        log.info("【第二次执行本地事务】消息体参数：transactionId={}", transactionId);

        //从 t_mq_transaction_log  表查询是否有一个ID
        MqTransactionLog log=this.mqTransactionLogMpper.selectById(transactionId);
        //有问题
        if(null ==log){
            return RocketMQLocalTransactionState.ROLLBACK;
        }

        return  RocketMQLocalTransactionState.COMMIT;
    }
}
